//package de.arndtplc.gosleep;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream.GetField;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;

public class GoSleepMain {

	public final static String ACTION_GO_SLEEP = "gosleep";
	public final static String BIND_IP = "192.168.2.102";
	public final static String BLOCK_SLEEP_WHEN_IP_ACTIVE = "192.168.2.104";
	public final static String BLOCK_SLEEP_WHEN_USER_LOGIN = "mathias";
	public final static long IDLE_TIME_TILL_SLEEP = 900000; // 15min

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		long lastCheck = System.currentTimeMillis();

		try {
			DatagramSocket socket = null;
			while (true) {
				try {
					if (socket == null || !socket.isBound()
							|| socket.isClosed()) {
						socket = new DatagramSocket(39000,
								InetAddress.getByName(BIND_IP));
						socket.setSoTimeout(6000);
					}
					byte[] buf = new byte[7];
					DatagramPacket packet = new DatagramPacket(buf, buf.length);
					socket.receive(packet);
					int receivedByte = packet.getLength();
					ByteBuffer bb = ByteBuffer.wrap(packet.getData());
					if (receivedByte != 0) {
						String strRec = Charset.forName("UTF-8").decode(bb)
								.toString();
						System.out.print("Received: \"" + strRec + "\"");
						if (strRec.equalsIgnoreCase(ACTION_GO_SLEEP)) {
							if (canSleep()) {
								shutdown();
							} else {
								lastCheck = System.currentTimeMillis();
							}
						}
					}
				} catch (UnknownHostException uh) {
					System.out.print("Unknown host... wait and try again\n");
					socket = null;
					Thread.sleep(2000);
					continue;
				} catch (SocketTimeoutException st) {
					Thread.sleep(100);
					// check if idle time has reached
					if ((System.currentTimeMillis() - lastCheck) > IDLE_TIME_TILL_SLEEP) {
						System.out.print("Idle time reached...");
						try {
							if (canSleep()) {
								shutdown();
							}
						} catch (IOException e) {
							System.out.print(e.getLocalizedMessage());
						}
						lastCheck = System.currentTimeMillis();
					}
					continue;
				} catch (IOException e) {
					System.out.print(e.getLocalizedMessage() + "\n");
				}
				if (socket != null) {
					socket.close();
					socket = null;
				}
				Thread.sleep(1000);
			}

		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

	public static boolean canSleep() throws IOException, InterruptedException {
		Process who = Runtime.getRuntime().exec("who");
		who.waitFor();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				who.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
			System.out.print("\n" + line);
			if (line.contains(BLOCK_SLEEP_WHEN_USER_LOGIN)) {
				System.out.print("\n...keep alive, because user "
						+ BLOCK_SLEEP_WHEN_USER_LOGIN + " is logged in\n");
				return false;
			}
		}

		InetAddress alive = InetAddress.getByName(BLOCK_SLEEP_WHEN_IP_ACTIVE);
		if (alive.isReachable(1000)) {
			System.out.print("...keep alive, because IP "
					+ BLOCK_SLEEP_WHEN_IP_ACTIVE + " is alive\n");
			return false;
		}
		return true;
	}

	public static void shutdown() throws IOException, InterruptedException {
		System.out.print("...shutdown\n");
		Process p = Runtime.getRuntime().exec("init 0");
		p.waitFor();
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				p.getInputStream()));
		String line;
		while ((line = reader.readLine()) != null) {
			System.out.print(line);
		}
	}
}
